package com.df.my_net_game.net.websocket;


import com.df.my_net_game.net.base.GTcpServer;
import com.df.my_net_game.net.base.IServerCB;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.handler.codec.http.websocketx.BinaryWebSocketFrame;
import io.netty.handler.codec.http.websocketx.ContinuationWebSocketFrame;
import io.netty.handler.codec.http.websocketx.TextWebSocketFrame;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * @author Admin
 * @class MsgAdapter
 * @date 2024/4/3 15:49
 */
public class GWebsocketDefaultMsgHandler extends SimpleChannelInboundHandler<Object> {

	/**
	 * 日志
	 */
	Logger log = LoggerFactory.getLogger(GWebsocketDefaultMsgHandler.class);
	IServerCB iServerCB;
	ByteBuf b;
	GTcpServer server;


	public GWebsocketDefaultMsgHandler(IServerCB iServerCB, GTcpServer server) {
		this.iServerCB = iServerCB;
		this.server = server;
	}


	/***
	 * 数据处理
	 * 
	 * @author: Admin
	 * @date: 2024/4/3 15:49
	 * @param ctx
	 *            channel上下文
	 * @param o
	 *            数据
	 * @return: void
	 */
	@Override
	protected void channelRead0(ChannelHandlerContext ctx, Object o) throws Exception {
		if(server.getMsgType()==0){//二进制
			if(o instanceof TextWebSocketFrame){
				return;
			}
			if (o instanceof BinaryWebSocketFrame) {
				// 二进制数据
				BinaryWebSocketFrame frame = (BinaryWebSocketFrame) o;
				if (b == null)
				{
					b = ctx.alloc().heapBuffer();
				}
				b.writeBytes(frame.content());
				if (frame.isFinalFragment() )
				{
					handleMessage(ctx);
					b.clear();
				}
			} else if(o instanceof ContinuationWebSocketFrame) {
				// 二进制数据
				ContinuationWebSocketFrame frame = (ContinuationWebSocketFrame) o;
				b.writeBytes(frame.content());
				if (frame.isFinalFragment())
				{
					handleMessage( ctx);
					b.clear();
				}
			}
			return;
		}
		if(server.getMsgType()==1){//字符串
			if (o instanceof BinaryWebSocketFrame) {
				log.error("当前服务器只接收字符串数据，当前收到二进制帧，丢弃数据！");
				return;
			}
			if(o instanceof ContinuationWebSocketFrame) {
				// 二进制数据
				ContinuationWebSocketFrame frame = (ContinuationWebSocketFrame) o;
				b.writeBytes(frame.content());
				if (frame.isFinalFragment())
				{
					handleMessage( ctx);
					b.clear();
				}
			}else if (o instanceof TextWebSocketFrame) {
				TextWebSocketFrame frame = (TextWebSocketFrame) o;
				// 文本 String类型数据-直接返回数据
				// 二进制数据
				if (b == null)
				{
					b = ctx.alloc().heapBuffer();
				}
				b.writeBytes(frame.content());
				if (frame.isFinalFragment() )
				{
					handleMessage(ctx);
					b.clear();
				}
			}
		}

	}

	private void handleMessage(ChannelHandlerContext ctx){
		int msgLen = b.readableBytes();
		if (msgLen < 1) {
			return;
		}
		ByteBuf byteBuf = ctx.alloc().heapBuffer();
		// 消息内容写入-前4位是消息id,之后是消息内容
		b.writeBytes(byteBuf);
		try {
			Object realMsg = null;
			if(iServerCB!=null){
//				realMsg = iServerCB.decode(byteBuf,server);
			}else {
				log.error("未设置服务器回调，无法处理接收到的消息！");
			}
//			if(realMsg!=null){
//				server.getMsgDispatcher().dispatcherMsg(realMsg,ctx);
//			}
		} catch (Exception e) {
			e.printStackTrace();
		}finally {
			byteBuf.release();
		}
	}



	@Override
	public void channelActive(ChannelHandlerContext ctx) throws Exception {
		super.channelActive(ctx);
//		InetSocketAddress socketAddress = (InetSocketAddress) ctx.channel().remoteAddress();
//		String hostAddress = socketAddress.getAddress().getHostAddress();
//		Integer port = socketAddress.getPort();
//		log.info("Channel Active:  "+hostAddress+":"+port);
		try {
			if(iServerCB!=null){
				iServerCB.onConnected(ctx,server);
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	@Override
	public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
		cause.printStackTrace();
		try {
			if(iServerCB!=null){
				iServerCB.onException(ctx,cause,server);
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
//		ctx.channel().writeAndFlush(new CloseWebSocketFrame());
//		ctx.close();
		super.exceptionCaught(ctx, cause);
	}

	/***
	 * 断开连接时触发 新建连接 -> handlerAdded -> channelRegistered -> channelActive ->
	 * channelRead | \/ 关闭连接 <- handlerRemoved <- channelUnregistered <-
	 * channelInactive <- channelReadComplete
	 * 
	 * @author: Admin
	 * @date: 2024/4/7 18:01
	 * @param ctx
	 *            Channel上下文
	 * @return: void
	 */
	@Override
	public void handlerRemoved(ChannelHandlerContext ctx) throws Exception {
		try {
			if(iServerCB!=null){
				iServerCB.onDisconnected(ctx,server);
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}
